/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.alibaba.nacos.naming.consistency;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.naming.pojo.Record;

import java.util.Optional;

/**
 * 所有要派生的实现的一致性服务.
 *
 * <p>我们发布这个一致性服务是为了将特定的一致性实现与业务逻辑解耦，用户不应该知道正在使用什么一致性协议.
 *
 * <p>通过这种方式，我们还为用户提供了扩展底层一致性协议的空间，只要它们遵守我们的一致性基线.
 *
 * @author nkorange
 * @since 1.0.0
 */
public interface ConsistencyService {
    
    /**
     * 将数据以键值的形式存储到Nacos集群.
     *
     * @param key   数据的键，全局唯一
     * @param value 要存储的数据
     * @throws NacosException nacos exception
     */
    void put(String key, Record value) throws NacosException;
    
    /**
     * 从Nacos集群移除数据.
     *
     * @param key 数据的键
     * @throws NacosException nacos exception
     */
    void remove(String key) throws NacosException;
    
    /**
     * 从Nacos集群获取数据.
     *
     * @param key 数据的键
     * @return 键值对应的数据
     * @throws NacosException nacos exception
     */
    Datum get(String key) throws NacosException;
    
    /**
     * 监听数据的变化.
     *
     * @param key      数据的键
     * @param listener 回调函数
     * @throws NacosException nacos exception
     */
    void listen(String key, RecordListener listener) throws NacosException;
    
    /**
     * 取消监听数据的变化.
     *
     * @param key      数据的键
     * @param listener 回调函数
     * @throws NacosException nacos exception
     */
    void unListen(String key, RecordListener listener) throws NacosException;
    
    /**
     * 获取错误信息.
     *
     * @return 错误信息.
     */
    Optional<String> getErrorMsg();
    
    /**
     * 获取一致性服务可用性.
     *
     * @return 可用返回true，否则返回false
     */
    boolean isAvailable();
}